package com.rockwell.sniffyHunter.test;

import java.util.HashMap;
import java.util.Map;

import junit.framework.Assert;

import android.annotation.SuppressLint;

import com.rockwell.sniffyhunter.model.Robot;
import com.rockwell.sniffyhunter.model.SnifferObject;
import com.rockwell.sniffyhunter.utils.DetectionIndex;
import com.rockwell.sniffyhunter.utils.IDetector;
import com.rockwell.sniffyhunter.utils.IRobotCommander;
import com.rockwell.sniffyhunter.utils.SnifferState;

public class SnifferStateTester extends UnitTestLooper {
	private FakeRobotSensors 		sensor;
	private Map<Integer, IDetector>	colorDetectors;
	private FakeTreasureDetector	treasureDetector;
	private IRobotCommander 		robotCommander;
	private Robot 					robot;
	private SnifferObject 			sniffer;
	private FakeTreasureCollector 	treasureCollector;
	
	@SuppressLint("UseSparseArrays") @SuppressWarnings("serial")
	@Override
	public void setUp() {
		sensor 				= new FakeRobotSensors();
		treasureDetector	= new FakeTreasureDetector();
		colorDetectors 		= new HashMap<Integer, IDetector>() {
							  {
								  put(DetectionIndex.TREASURE, treasureDetector);
								  put(DetectionIndex.OBSTACLE, new FakeColorDetector()/*obstacle detector*/); 
								  put(DetectionIndex.MAZE1, new FakeColorDetector()/*maze1 detector*/);
								  put(DetectionIndex.MAZE2, new FakeColorDetector()/*maze2 detector*/);
								  put(DetectionIndex.MAZE3, new FakeColorDetector()/*maze3 detector*/);
								  put(DetectionIndex.DROPZONE, new FakeColorDetector()/*dropZone detector*/);
								  put(DetectionIndex.MAZE_EXIT, new FakeColorDetector()/*dropZone detector*/);
							  }};
		robotCommander 		= new DummyRobotCommander();
		treasureCollector 	= new FakeTreasureCollector();
		
		robot 				= new Robot(0, 0,
								1 /*start Zone*/,
								sensor, 
								robotCommander, 
								null/*maze*/, 
								null/*solver*/, 
								colorDetectors, 
								treasureCollector);
		sniffer 			= new SnifferObject(robot);
	}
	
	@Override
	public void tearDown() {

	}
	
	public void testFoundTreasure() {
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.START);
		sniffer.PerformAction();
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.ROTATE_FOR_FIRST_SCAN);
		
		loopUntilCondition(sniffer, SnifferState.SCAN);
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.SCAN);

		sensor.m_hasFrontDistanceSensor = true;
		loopUntilCondition(sniffer, SnifferState.INDEX_ROTATE);
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.INDEX_ROTATE);
		
		loopUntilCondition(sniffer, SnifferState.SCAN);
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.SCAN);
		
		sensor.m_detectFrontWall = true;
		loopUntilCondition(sniffer, SnifferState.INDEX_ROTATE);
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.INDEX_ROTATE);
		
		loopUntilCondition(sniffer, SnifferState.SCAN);
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.SCAN);
		
		treasureDetector.m_isPresent = true;
		sniffer.PerformAction();
		Assert.assertTrue(sniffer.IsTreasureFound());
	}
	
	public void testBasketFull() {
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.START);
		sniffer.PerformAction();
		
		treasureCollector.m_isFull = true;		
		loopUntilCondition(sniffer, SnifferState.SCAN);
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.SCAN);

		sniffer.PerformAction();
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.START);
		Assert.assertTrue(sniffer.IsBasketFull());
	}
	
	public void testSniffCompleted() {
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.START);
		sniffer.PerformAction();
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.ROTATE_FOR_FIRST_SCAN);
		
		loopUntilCondition(sniffer, SnifferState.MAP_DISCOVERED_AREA);
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.MAP_DISCOVERED_AREA);
		
		sniffer.PerformAction();
		Assert.assertEquals(sniffer.getStateMachine(), SnifferState.ROTATE_BACK);
		
		loopUntilCondition(sniffer, SnifferState.START);
		Assert.assertTrue(sniffer.IsSniffCompleted());
	}
}
